package cc.owoo.godpen.structure;

import java.lang.reflect.Array;
import java.util.ArrayList;

/**
 * 分块数组
 * Created by nimensei
 * 2022-05-08 上午 11:48
 **/
public class BlockArrayList<T> {
    private final ArrayList<T[]> arrayList = new ArrayList<>();// 数据
    private final Class<T> itemClass;// 元素类型
    private final int block;// 块大小
    public int size;// 数组长度

    /**
     * 创建分块数组，每个块1000个
     *
     * @param itemClass 元素类型
     */
    public BlockArrayList(Class<T> itemClass) {
        this(itemClass, 1000);
    }

    /**
     * 创建分块数组
     *
     * @param itemClass 元素类型
     * @param block     块大小
     */
    public BlockArrayList(Class<T> itemClass, int block) {
        if (itemClass == null)
            throw new NullPointerException("元素类型不能为空");
        this.block = Math.max(1, block);
        this.itemClass = itemClass;
    }

    /**
     * 向数组添加一个元素
     *
     * @param item 被添加的元素
     */
    public void add(T item) {
        if (size / block >= arrayList.size())
            arrayList.add((T[]) Array.newInstance(itemClass, block));
        arrayList.get(size / block)[size % block] = item;
        ++size;
    }


    /**
     * 获取指定下标的元素
     *
     * @param index 元素下标
     * @return 元素
     */
    public T get(int index) {
        if (index < 0 || index >= size)
            throw new ArrayIndexOutOfBoundsException("下标越界：index = " + index + ", size = " + size);
        return arrayList.get(index / block)[index % block];
    }

    /**
     * 获取数组长度
     *
     * @return 数组长度
     */
    public int size() {
        return size;
    }
}
